package com.gkzf.ai.module.crm.service.creditReport;

import com.gkzf.ai.module.crm.controller.admin.creditReport.vo.admittancecondition.QuotaFormulaValue;
import com.gkzf.ai.module.crm.dal.dataobject.creditReport.UserCreditReportAdmittanceConditionDO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * 额度测算service
 */
@Slf4j
@Service
public class CreditLimitServiceImpl implements CreditLimitService{


    /**
     * 获取月收入
     * @param creditReportAdmittanceCondition 用户补充信息
     * @return 月收入
     */
    public BigDecimal getMonthlyIncome(UserCreditReportAdmittanceConditionDO creditReportAdmittanceCondition){
            // 为null 返回 0
            if (null == creditReportAdmittanceCondition) {
                return BigDecimal.ZERO;
            }
            if (null != creditReportAdmittanceCondition.getAnnualIncome()) {
                // 值小于等于0 返回 0
                if (creditReportAdmittanceCondition.getAnnualIncome().compareTo(BigDecimal.ZERO) <= 0) {
                    return BigDecimal.ZERO;
                } else {
                    return creditReportAdmittanceCondition.getAnnualIncome().divide(new BigDecimal("12"), 2, RoundingMode.HALF_UP);
                }
            }
        return BigDecimal.ZERO;
    }

    /**
     * 公积金双边缴纳金额
     * @param creditReportAdmittanceCondition 银行补充信息
     * @return 公积金双边缴纳金额
     */
    @Override
    public BigDecimal getProvidentFundMoney(UserCreditReportAdmittanceConditionDO creditReportAdmittanceCondition) {
        if (null != creditReportAdmittanceCondition){
            Double creditReportBilateralFundBase = creditReportAdmittanceCondition.getCreditReportBilateralFundBase();
            if (null != creditReportBilateralFundBase && creditReportBilateralFundBase > 0){
                return BigDecimal.valueOf(creditReportBilateralFundBase);
            }
        }
        return BigDecimal.ZERO;
    }

    /**
     * 获取单位性质
     * @param creditReportAdmittanceCondition 用户补充信息
     * @return 单位性质
     */
    @Override
    public Integer getUnit(UserCreditReportAdmittanceConditionDO creditReportAdmittanceCondition) {
        // 为null 返回 0
        if (null == creditReportAdmittanceCondition) {
            return null;
        }
        return Integer.valueOf(creditReportAdmittanceCondition.getUnitNature());
    }

    /**
     *  获取按揭月供
     * @param creditReportAdmittanceCondition 用户补充信息
     * @return 月供
     */
    @Override
    public BigDecimal getMortgageMonthlyPayment(UserCreditReportAdmittanceConditionDO creditReportAdmittanceCondition) {
        // 为null 返回 0
        if (null == creditReportAdmittanceCondition) {
            return BigDecimal.ZERO;
        }
        String mortgageMonthlyPayment = creditReportAdmittanceCondition.getMortgageMonthlyPayment();
        if (StringUtils.isNotBlank(mortgageMonthlyPayment)) {
            return new BigDecimal(mortgageMonthlyPayment);
        }
        return BigDecimal.ZERO;
    }

    /**
     * 房产价值
     * @param admittanceCondition 用户补充信息
     * @return 房产价值
     */
    @Override
    public BigDecimal getPropertyValue(UserCreditReportAdmittanceConditionDO admittanceCondition) {
        List<BigDecimal> propertyValue = new ArrayList<>();
        if (null != admittanceCondition) {
            propertyValue.add(Optional.ofNullable(admittanceCondition.getMortgageValue()).orElse(BigDecimal.ZERO));
            propertyValue.add(Optional.ofNullable(admittanceCondition.getFullPaymentValue()).orElse(BigDecimal.ZERO));
            propertyValue.add(Optional.ofNullable(admittanceCondition.getHypothecateValue()).orElse(BigDecimal.ZERO));
        }
        if (propertyValue.isEmpty()) {
            return BigDecimal.ZERO;
        }
        // 取 全款 按揭 抵押 中的最大值
        return Collections.max(propertyValue);
    }

    /**
     * 月收入前置条件
     * @param quotaFormulaValueList 单位性质要求集合
     * @param creditReportAdmittanceCondition 用户补充信息
     * @return 单位性质前置条件符合的对象
     */
    @Override
    public List<QuotaFormulaValue> monthlyIncomePrecondition(List<QuotaFormulaValue> quotaFormulaValueList,UserCreditReportAdmittanceConditionDO creditReportAdmittanceCondition) {
        // 月收入等于0 直接不通过
        List<QuotaFormulaValue> result = new ArrayList<>();
        BigDecimal monthlyIncome = getMonthlyIncome(creditReportAdmittanceCondition);
        log.info("月收入：{}", monthlyIncome);
        if (monthlyIncome.compareTo(BigDecimal.ZERO) == 0){
            return result;
        }
        for (QuotaFormulaValue creditLimit : quotaFormulaValueList) {
            /*
              * 满足返回集合
              * 自动识别 min 和 max 的顺序并判断是否在闭区间内
             */
            log.info("产品月收入标准 {} -- {}", creditLimit.getStart(), creditLimit.getEnd());
            if (isBetween(monthlyIncome, creditLimit.getStart(), creditLimit.getEnd())) {
                log.info("满足要求公式 {}",creditLimit);
                result.add(creditLimit);
            }
        }
        return result;
    }

    /**
     * 房产前置条件
     * @param quotaFormulaValue 单位性质要求集合
     * @param creditReportAdmittanceCondition 用户补充信息
     * @return 单位性质前置条件符合的对象
     */
    @Override
    public List<QuotaFormulaValue> propertyValuePrecondition(List<QuotaFormulaValue> quotaFormulaValue, UserCreditReportAdmittanceConditionDO creditReportAdmittanceCondition) {
        List<QuotaFormulaValue> result = new ArrayList<>();
        BigDecimal propertyValue = getPropertyValue(creditReportAdmittanceCondition);
        log.info("用户房产价值:{}", propertyValue);
        // 房产价值等于 0 直接不通过
        if (propertyValue.compareTo(BigDecimal.ZERO) == 0){
            return result;
        }
        /*
            房产有多个公式都匹配上时 添加进集合 计算额度取最大值
         */
        for (QuotaFormulaValue creditLimit : quotaFormulaValue) {
            /*
              * 自动识别 min 和 max 的顺序并判断是否在闭区间内
             */
            log.info("产品房产标准 {} -- {}", creditLimit.getStart(), creditLimit.getEnd());
            if (isBetween(propertyValue, creditLimit.getStart(), creditLimit.getEnd())) {
                log.info("满足要求公式 {}",creditLimit);
                result.add(creditLimit);
            }
        }
        return result;
    }

    /**
     * 单位性质前置条件
     * @param quotaFormulaValue 单位性质要求集合
     * @param creditReportAdmittanceCondition 用户补充信息
     * @return 单位性质前置条件符合的对象
     */
    @Override
    public List<QuotaFormulaValue> unitPrecondition(List<QuotaFormulaValue> quotaFormulaValue,UserCreditReportAdmittanceConditionDO creditReportAdmittanceCondition) {
        List<QuotaFormulaValue> result = new ArrayList<>();
        Integer unitNature = getUnit(creditReportAdmittanceCondition);
        log.info("用户单位性质:{}", unitNature);
        if (null == unitNature) {
            return result;
        }
        /*
            月收入有多个公式都匹配上时 添加进集合 计算额度取最大值
         */
        for (QuotaFormulaValue creditLimit : quotaFormulaValue) {
            log.info("产品单位性质标准 {}", creditLimit.getIndex());
            // 单位性质等于 返回 true
            if (Objects.equals(unitNature, creditLimit.getIndex())) {
                log.info("满足要求公式 {}",creditLimit);
                result.add(creditLimit);
            }
        }
        return result;
    }

    /**
     *  查询用户按揭月供
     * @param quotaFormulaValue 按揭月供集合
     * @param creditReportAdmittanceCondition 用户补充信息
     * @return 满足的公式集合
     */
    @Override
    public List<QuotaFormulaValue> mortgageMonthlyPayment(List<QuotaFormulaValue> quotaFormulaValue,UserCreditReportAdmittanceConditionDO creditReportAdmittanceCondition) {
        List<QuotaFormulaValue> result = new ArrayList<>();
        BigDecimal mortgageMonthlyPayment = getMortgageMonthlyPayment(creditReportAdmittanceCondition);
        log.info("用户按揭月供:{}", mortgageMonthlyPayment);
        if (mortgageMonthlyPayment.compareTo(BigDecimal.ZERO) == 0){
            return result;
        }
        for (QuotaFormulaValue creditLimit : quotaFormulaValue) {
            log.info("产品按揭月供标准 {}-{}", creditLimit.getStart(), creditLimit.getEnd());
            // 按揭月供等于 返回 true
            if (isBetween(mortgageMonthlyPayment, creditLimit.getStart(), creditLimit.getEnd())) {
                log.info("满足要求公式 {}",creditLimit);
                result.add(creditLimit);
            }
        }
        return result;
    }

    /**
     *  匹配满足公积金双边缴纳金融对象
     * @param quotaFormulaValue 公式集合
     * @param creditReportAdmittanceCondition 用户补充信息
     * @return  满足条件对象
     */
    @Override
    public List<QuotaFormulaValue> providentFundMoney(List<QuotaFormulaValue> quotaFormulaValue, UserCreditReportAdmittanceConditionDO creditReportAdmittanceCondition) {
        List<QuotaFormulaValue> result = new ArrayList<>();
        BigDecimal providentFundMoney = getProvidentFundMoney(creditReportAdmittanceCondition);
        log.info("用户公积金双边缴纳:{}", providentFundMoney);
        if (providentFundMoney.compareTo(BigDecimal.ZERO) == 0){
            return result;
        }
        for (QuotaFormulaValue creditLimit : quotaFormulaValue) {
            log.info("产品公积金双边缴纳标准 {}-{}", creditLimit.getStart(), creditLimit.getEnd());
            // 单位性质等于 返回 true
            if (isBetween(providentFundMoney, creditLimit.getStart(), creditLimit.getEnd())) {
                log.info("满足要求公式 {}",creditLimit);
                result.add(creditLimit);
            }
        }
        return result;
    }


    /**
     * 自动识别 min 和 max 的顺序并判断是否在闭区间内
     */
    public static boolean isBetween(BigDecimal value, BigDecimal a, BigDecimal b) {
        BigDecimal min = a.min(b);
        BigDecimal max = a.max(b);
        return value.compareTo(min) >= 0 && value.compareTo(max) <= 0;
    }
}
